
#include "gd32f30x.h"
#include "systick.h"
#include <stdio.h>

#include "usart.h"

#define USART1_RDATA_ADDRESS      ((uint32_t)&USART_DATA(USART1))
#define ARRAYNUM(arr_nanme)      (uint32_t)(sizeof(arr_nanme) / sizeof(*(arr_nanme)))

uint8_t usart1_rx_buffer[USART2_RECEIVE_DATA_LENGTH];
__IO uint16_t usart1_rxcount = 0; 

#ifdef BUILD_PLATFORM_KEIL
// printf 
int fputc(int ch, FILE *f)
{
    usart_data_transmit(USART0, (uint8_t)ch);
    while(RESET == usart_flag_get(USART0, USART_FLAG_TBE));
    return ch;
}
#endif

int _write (int fd, char *pBuffer, int size)
{
	uint32_t i;
	for (i = 0; i < size; i++)
	{
		usart_data_transmit(USART0, (uint8_t)pBuffer[i]);
        while(RESET == usart_flag_get(USART0, USART_FLAG_TBE));	
	}
	return size;
}

int init_usart0(void)
{
	/* enable GPIO clock */
    rcu_periph_clock_enable(RCU_GPIOA);
    /* enable USART clock */
    rcu_periph_clock_enable(RCU_USART0);
    /* connect port to USARTx_Tx */
    gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
    /* connect port to USARTx_Rx */
    gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_10);
    /* USART configure */
    usart_deinit(USART0);
    usart_baudrate_set(USART0, 115200U);
    usart_receive_config(USART0, USART_RECEIVE_ENABLE);
    usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
    usart_enable(USART0);

	return 0;
}

#ifdef ENABLE_USART1_TEST
static void nvic_usart1_config(void)
{
    nvic_irq_enable(USART1_IRQn, 1, 0);
}

static void dma_usart1_config(void)
{
    dma_parameter_struct dma_init_struct;
    rcu_periph_clock_enable(RCU_DMA0);
    
    /* deinitialize DMA channel5 (USART1 rx) */
    dma_deinit(DMA0, DMA_CH5);
    dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;
    dma_init_struct.memory_addr = (uint32_t)usart1_rx_buffer;
    dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
    dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
    dma_init_struct.number = USART2_RECEIVE_DATA_LENGTH;
    dma_init_struct.periph_addr = USART1_RDATA_ADDRESS;
    dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
    dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
    dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
    dma_init(DMA0, DMA_CH5, &dma_init_struct);
    /* configure DMA mode */
    dma_circulation_disable(DMA0, DMA_CH5);
    /* enable DMA channel5 */
    dma_channel_enable(DMA0, DMA_CH5); 
}

static void usart1_config(void)
{
    /* enable GPIO clock */
    rcu_periph_clock_enable(RCU_GPIOA);

    /* enable USART clock */
    rcu_periph_clock_enable(RCU_USART1);
    
    /* connect port to USARTx_Tx */
    gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2);

    /* connect port to USARTx_Rx */
    gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_3);

    /* configure USART */
    usart_deinit(USART1);
    usart_baudrate_set(USART1, 115200U);
    usart_receive_config(USART1, USART_RECEIVE_ENABLE);
    usart_transmit_config(USART1, USART_TRANSMIT_ENABLE);
    usart_dma_receive_config(USART1, USART_RECEIVE_DMA_ENABLE);
    usart_enable(USART1);
}

int init_usart1(void)
{
    nvic_usart1_config();
    dma_usart1_config();
    usart1_config();
    usart_interrupt_enable(USART1, USART_INT_IDLE);
    return 0;
}

void usart1_send_string(uint8_t *pBuffer,uint16_t size)
{
    uint32_t i;
	for (i = 0; i < size; i++)
	{
		usart_data_transmit(USART1, (uint8_t)pBuffer[i]);
        while(RESET == usart_flag_get(USART1, USART_FLAG_TBE));	
	}
}
#endif